package com.fourhats.services.impl;

import java.util.ArrayList;
import java.util.List;

import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;

import com.fourhats.dao.MarketDAO;
import com.fourhats.dao.UserDAO;
import com.fourhats.dao.VisitEntityDAO;
import com.fourhats.model.Market;
import com.fourhats.model.ObjectTypes;
import com.fourhats.model.User;
import com.fourhats.services.MarketService;
import com.fourhats.services.dto.MarketDto;
import com.fourhats.services.dto.PublicMarketDto;
import com.fourhats.services.util.Page;

public class MarketServiceImpl implements MarketService {

	@Autowired
	private Mapper mapper;
	
	@Autowired
	private MarketDAO marketDAO;
	
	@Autowired
	private UserDAO userDAO;

	@Autowired
	private VisitEntityDAO visitEntityDAO;
	
	public List<MarketDto> getMarketsByKeyword(String keyword) {
		List<Market> markets = marketDAO.getMarketsByKeyword(keyword);
		return this.getDtos(markets);
	}
	
	public Page<MarketDto> getMarketsPageByKeyword(String keyword, int pageNumber, int pageSize) {
		List<Market> markets = marketDAO.getMarketsByKeyword(keyword);
		return this.getPage(markets, pageNumber, pageSize);
	}

	public MarketDto getMarketById(long marketId) {
		return this.getDto(marketDAO.getById(marketId));
	}
	
	public PublicMarketDto getPublicMarketById(long marketId) {
		return this.getPublicDto(marketDAO.getById(marketId));
	}

	public List<MarketDto> getRandomlyHighlightMarkets(int maxResult) {
		List<Market> markets = marketDAO.getRandomlyHighlightMarkets(maxResult);
		return this.getDtos(markets);
	}
	
	public Page<MarketDto> getAllMarkets(int first, int maxResult) {
		List<Market> markets = marketDAO.getAllMarkets();
		return this.getPage(markets, first, maxResult);
	}
	
	public MarketDto getMarketByUser(long userId) {
		if(this.marketDAO.hasMarket(userId)) {
			Market market = marketDAO.getMarketByUser(userId);
			return this.getDto(market);
		} else {
			return null;
		}
	}
	
	public boolean hasMarket(long userId) {
		return this.marketDAO.hasMarket(userId);
	}
	
	public boolean existMarketWithName(String marketName, long userId) {
		return this.marketDAO.existMarketWithName(marketName, userId);
	}
	
	public void createMarket(MarketDto market, long userId) {
		User user = userDAO.getById(userId);
		Market newMarket = new Market(market.getName(), market.getSubtitle(), market.getDescription(), 
			market.getAddress(), market.getPhone(), market.getWeb(), market.getEmail(), market.getImagePath(), 
				market.isEnable(), market.isHighlight(), user, market.getLatitude(), market.getLongitude(),
				market.getEnvironmentAffect(), market.getQualityImprovement(), market.getOrganization(), market.getRecognitionReceived());
		
		marketDAO.add(newMarket);
	}
	
	public void editMarket(MarketDto market) {
		Market marketToEdit = marketDAO.getById(market.getId());
		marketToEdit.setName(market.getName());
		marketToEdit.setSubtitle(market.getSubtitle());
		marketToEdit.setDescription(market.getDescription());
		marketToEdit.setAddress(market.getAddress());
		marketToEdit.setPhone(market.getPhone());
		marketToEdit.setEmail(market.getEmail());
		marketToEdit.setWeb(market.getWeb());
		marketToEdit.setImagePath(market.getImagePath());
		marketToEdit.setLatitude(market.getLatitude());
		marketToEdit.setLongitude(market.getLongitude());
		marketToEdit.setEnvironmentAffect(market.getEnvironmentAffect());
		marketToEdit.setQualityImprovement(market.getQualityImprovement());
		marketToEdit.setOrganization(market.getOrganization());
		marketToEdit.setRecognitionReceived(market.getRecognitionReceived());
		marketDAO.add(marketToEdit);
	}
	
	public void desactivateMarket(long marketId) {
		Market market = marketDAO.getById(marketId);
		market.setEnable(false);
		marketDAO.add(market);
	}

	public void activateMarket(long marketId) {
		Market market = marketDAO.getById(marketId);
		market.setEnable(true);
		marketDAO.add(market);
	}
	
	private List<MarketDto> getDtos(List<Market> markets) {
		List<MarketDto> dtos = new ArrayList<MarketDto>();
		for(Market m : markets) {
			dtos.add(this.getDto(m));
		}
		
		return dtos;
	}
	
	private MarketDto getDto(Market market) {
		MarketDto marketDto = mapper.map(market, MarketDto.class);
		return this.populateMarket(marketDto);
	}
	
	private PublicMarketDto getPublicDto(Market market){
		PublicMarketDto marketDto = mapper.map(market, PublicMarketDto.class);
		return marketDto;
	}
	
	private MarketDto populateMarket(MarketDto market) {
		market.setQtyVisits(this.visitEntityDAO.getQtyVisits(market.getId(), ObjectTypes.MARKET.getValue()));
		return market;
	}
	
	@SuppressWarnings("unchecked")
	private Page<MarketDto> getPage(List<Market> markets, int pageNumber, int pageSize) {
		int first = (pageNumber - 1) * pageSize;
		int last = pageNumber * pageSize > markets.size() ? markets.size() : pageNumber * pageSize;
		return (Page<MarketDto>) Page.create(this.getDtos(markets.subList(first, last)), pageNumber, pageSize, markets.size());
	}
}